
package com.idealighter.game.robot.scheduler;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;

import com.idealighter.game.core.common.Game;
import com.idealighter.game.core.constant.room.RoomActiveConstant;
import com.idealighter.game.core.util.NetUtil;
import com.idealighter.game.dictionary.dic.BaccaratRoomDic;
import com.idealighter.game.dictionary.dic.BairenniuniuRoomDic;
import com.idealighter.game.dictionary.dic.DoudizhuMatchRoomDic;
import com.idealighter.game.dictionary.dic.DoudizhuRoomDic;
import com.idealighter.game.dictionary.dic.ErrenniuniuRoomDic;
import com.idealighter.game.dictionary.dic.ErrentexaporkerRoomDic;
import com.idealighter.game.dictionary.dic.FoursShopRoomDic;
import com.idealighter.game.dictionary.dic.GamesDic;
import com.idealighter.game.dictionary.dic.HappyfiveRoomDic;
import com.idealighter.game.dictionary.dic.HorseRaceRoomDic;
import com.idealighter.game.dictionary.dic.JcbyRoomDic;
import com.idealighter.game.dictionary.dic.LkpyRoomDic;
import com.idealighter.game.dictionary.dic.RobotConfigDic;
import com.idealighter.game.dictionary.dic.SharkRoomDic;
import com.idealighter.game.dictionary.dic.ShuihuRoomDic;
import com.idealighter.game.dictionary.dic.SirenniuniuRoomDic;
import com.idealighter.game.dictionary.dic.TexaporkerRoomDic;
import com.idealighter.game.dictionary.dic.TongbiniuniuRoomDic;
import com.idealighter.game.dictionary.dic.WeishuwuRoomDic;
import com.idealighter.game.dictionary.dic.WknhRoomDic;
import com.idealighter.game.dictionary.dic.XzddRoomDic;
import com.idealighter.game.dictionary.dic.ZhajinhuaRoomDic;
import com.idealighter.game.dictionary.domain.BaccaratRoomDomain;
import com.idealighter.game.dictionary.domain.BairenniuniuRoomDomain;
import com.idealighter.game.dictionary.domain.ErrenniuniuRoomDomain;
import com.idealighter.game.dictionary.domain.ErrentexaporkerRoomDomain;
import com.idealighter.game.dictionary.domain.FoursShopRoomDomain;
import com.idealighter.game.dictionary.domain.GamesDomain;
import com.idealighter.game.dictionary.domain.HappyfiveRoomDomain;
import com.idealighter.game.dictionary.domain.HorseRaceRoomDomain;
import com.idealighter.game.dictionary.domain.JcbyRoomDomain;
import com.idealighter.game.dictionary.domain.LkpyRoomDomain;
import com.idealighter.game.dictionary.domain.RobotConfigDomain;
import com.idealighter.game.dictionary.domain.SharkRoomDomain;
import com.idealighter.game.dictionary.domain.ShuihuRoomDomain;
import com.idealighter.game.dictionary.domain.SirenniuniuRoomDomain;
import com.idealighter.game.dictionary.domain.TexaporkerRoomDomain;
import com.idealighter.game.dictionary.domain.TongbiniuniuRoomDomain;
import com.idealighter.game.dictionary.domain.WeishuwuRoomDomain;
import com.idealighter.game.dictionary.domain.WknhRoomDomain;
import com.idealighter.game.dictionary.domain.ZhajinhuaRoomDomain;
import com.idealighter.game.dictionary.domwrapper.RobotConfigDomWrapper;
import com.idealighter.game.games.baccarat.BaccaratPlayer;
import com.idealighter.game.games.bairenniuniu.BaiRenNiuNiuPlayer;
import com.idealighter.game.games.errenniuniu.ErRenNiuNiuPlayer;
import com.idealighter.game.games.errentexaspoker.ErrenTexaspokerPlayer;
import com.idealighter.game.games.foursshop.FoursShopPlayer;
import com.idealighter.game.games.fqzs.SharkPlayer;
import com.idealighter.game.games.happyfive.HappyFivePlayer;
import com.idealighter.game.games.horserace.HorseRacePlayer;
import com.idealighter.game.games.jcby.JcbyPlayer;
import com.idealighter.game.games.lkby.LkbyPlayer;
import com.idealighter.game.games.shuihu.ShuiHuPlayer;
import com.idealighter.game.games.sirenniuniu.SiRenNiuNiuPlayer;
import com.idealighter.game.games.texaspoker.TexaspokerPlayer;
import com.idealighter.game.games.tongbiniuniu.TongBiNiuNiuPlayer;
import com.idealighter.game.games.weishuwu.WeishuwuPlayer;
import com.idealighter.game.games.wknh.WknhPlayer;
import com.idealighter.game.games.zjh.ZjhPlayer;
import com.idealighter.game.message.MessageFactory;
import com.idealighter.game.robot.core.Player;
import com.idealighter.game.robot.datadb.domain.RobotDomain;
import com.idealighter.game.robot.datadb.mapper.RobotMapper;
import com.idealighter.utils.code.RandCodeUtil;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 机器人玩家Scheduler.
 *
 */
@Singleton
public class PlayerScheduler {
  private static final Logger LOG = LoggerFactory.getLogger(PlayerScheduler.class);

  // 服务器ip
  private final String serverIp;
  // 服务器端口
  private final int serverPort;
  private final RobotMapper robotMapper;
  private final RobotConfigDic robotConfigDic;
  // 机器人玩家定时调度器(单线程)
  private final ScheduledExecutorService scheduler =
      Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "robotPlayer-scheduler"));

  // 所有可用机器人(不包含已冻结的)Dom
  private static final ConcurrentHashMap<Long, RobotDomain> robotDoms = new ConcurrentHashMap<>();
  // 已经创建的机器人
  private final ConcurrentHashMap<Long, Player> players = new ConcurrentHashMap<>();

  private BaccaratRoomDic baccaratRoomDic;

  private BairenniuniuRoomDic bairenniuniuRoomDic;

  private ErrenniuniuRoomDic errenniuniuRoomDic;

  private ErrentexaporkerRoomDic errentexaporkerRoomDic;

  private FoursShopRoomDic foursShopRoomDic;

  private SharkRoomDic sharkRoomDic;

  private HappyfiveRoomDic happyfiveRoomDic;

  private HorseRaceRoomDic horseRaceRoomDic;

  private JcbyRoomDic jcbyRoomDic;

  private LkpyRoomDic lkpyRoomDic;

  private ShuihuRoomDic shuihuRoomDic;

  private SirenniuniuRoomDic sirenniuniuRoomDic;

  private TexaporkerRoomDic texaporkerRoomDic;

  private TongbiniuniuRoomDic tongbiniuniuRoomDic;

  private WeishuwuRoomDic weishuwuRoomDic;

  private WknhRoomDic wknhRoomDic;

  private ZhajinhuaRoomDic zhajinhuaRoomDic;

  private GamesDic gamesDic;

  /**
   * 构造函数.
   * 
   * @param mapper .
   * @param dic .
   * @param serverIp .
   * @param serverPort .
   */
  @Inject
  public PlayerScheduler(RobotMapper mapper, RobotConfigDic dic,
      @Named("server.ip") String serverIp, @Named("server.tcpPort") int serverPort,
      BaccaratRoomDic baccaratRoomDic, BairenniuniuRoomDic bairenniuniuRoomDic,
      DoudizhuMatchRoomDic doudizhuMatchRoomDic, DoudizhuRoomDic doudizhuRoomDic,
      ErrenniuniuRoomDic errenniuniuRoomDic, ErrentexaporkerRoomDic errentexaporkerRoomDic,
      FoursShopRoomDic foursShopRoomDic, SharkRoomDic sharkRoomDic,
      HappyfiveRoomDic happyfiveRoomDic, HorseRaceRoomDic horseRaceRoomDic, JcbyRoomDic jcbyRoomDic,
      LkpyRoomDic lkpyRoomDic, ShuihuRoomDic shuihuRoomDic, SirenniuniuRoomDic sirenniuniuRoomDic,
      TexaporkerRoomDic texaporkerRoomDic, TongbiniuniuRoomDic tongbiniuniuRoomDic,
      WeishuwuRoomDic weishuwuRoomDic, WknhRoomDic wknhRoomDic, XzddRoomDic xzddRoomDic,
      ZhajinhuaRoomDic zhajinhuaRoomDic, GamesDic gamesDic) {
    this.robotMapper = mapper;
    this.robotConfigDic = dic;
    this.serverIp = serverIp;
    this.serverPort = serverPort;
    this.baccaratRoomDic = baccaratRoomDic;
    this.bairenniuniuRoomDic = bairenniuniuRoomDic;
    this.errenniuniuRoomDic = errenniuniuRoomDic;
    this.errentexaporkerRoomDic = errentexaporkerRoomDic;
    this.foursShopRoomDic = foursShopRoomDic;
    this.sharkRoomDic = sharkRoomDic;
    this.happyfiveRoomDic = happyfiveRoomDic;
    this.horseRaceRoomDic = horseRaceRoomDic;
    this.jcbyRoomDic = jcbyRoomDic;
    this.lkpyRoomDic = lkpyRoomDic;
    this.shuihuRoomDic = shuihuRoomDic;
    this.sirenniuniuRoomDic = sirenniuniuRoomDic;
    this.texaporkerRoomDic = texaporkerRoomDic;
    this.tongbiniuniuRoomDic = tongbiniuniuRoomDic;
    this.weishuwuRoomDic = weishuwuRoomDic;
    this.wknhRoomDic = wknhRoomDic;
    this.zhajinhuaRoomDic = zhajinhuaRoomDic;
    this.gamesDic = gamesDic;


    // 加载机器人
    loadRobots();
  }

  /**
   * 加载机器人数据 .
   */
  private void loadRobots() {
    List<RobotDomain> robotsList = robotMapper.selectAll();
    Collections.shuffle(robotsList);

    for (RobotDomain robotDom : robotsList) {
      if (robotDom.isLocked()) {
        continue;
      }
      robotDoms.put(robotDom.getId(), robotDom);
    }
  }

  /**
   * 重新加载服务器机器人 .
   */
  public void reloadRobots() {
    List<RobotDomain> robotsList = robotMapper.selectAll();
    Collections.shuffle(robotsList);

    for (RobotDomain robotDom : robotsList) {
      long playerId = robotDom.getId();

      if (robotDom.isLocked()) {
        Player player = players.get(playerId);
        if (player != null) {
          LOG.info("玩家[{}][{}]被冻结退出游戏", robotDom.getPlayerName(), playerId);
          player.logout();
        }
      } else {
        robotDoms.putIfAbsent(playerId, robotDom);
      }
    }

    LOG.info("重新加载机器人成功");
  }

  /**
   * 启动，每隔一分钟schedule一次机器人玩家 .
   */
  public void startUp() {
    MessageFactory.init();
    scheduler.scheduleWithFixedDelay(this::schedulePlayers, 0, 1, TimeUnit.MINUTES);
    // scheduler.scheduleWithFixedDelay(this::schedulePlayers, 0, 3, TimeUnit.SECONDS);
    LOG.info("机器人服务器启动成功");
  }


  /**
   * 重新加载游戏 .
   *
   * @author abin
   * @date 2018年5月16日 上午10:20:50
   */
  public void reloadGame() {
    LOG.info("重新加载游戏列表");
    gamesDic.load();
  }

  /**
   * 重新加载房间 .
   *
   * @author abin
   * @date 2018年5月2日 下午7:25:46
   * @param gameId 游戏id;
   */
  public void reloadRoom(Integer gameId) {
    switch (Game.getGame(gameId)) {
      case BAIREN_NIUNIU:
        bairenniuniuRoomDic.load();
        break;
      case ERREN_NIUNIU:
        errenniuniuRoomDic.load();
        break;
      case ERREN_TEXAPOKER:
        errentexaporkerRoomDic.load();
        break;
      case FOURS_SHOP:
        foursShopRoomDic.load();
        break;
      case HAPPY_FIVE:
        happyfiveRoomDic.load();
        break;
      case HORCERACE:
        horseRaceRoomDic.load();
        break;
      case JCBY:
        jcbyRoomDic.load();
        break;
      case LKBY:
        lkpyRoomDic.load();
        break;
      case FQZS:
        sharkRoomDic.load();
        break;
      case SHUI_HU_ZHUAN:
        shuihuRoomDic.load();
        break;
      case SIREN_NIUNIU:
        sirenniuniuRoomDic.load();
        break;
      case TEXAPOKER:
        texaporkerRoomDic.load();
        break;
      case TONGBI_NIUNIU:
        tongbiniuniuRoomDic.load();
        break;
      case BACCARAT:
        baccaratRoomDic.load();
        break;
      case WEISHUWU:
        weishuwuRoomDic.load();
        break;
      case DOU_DI_ZHU: // 斗地主比赛机器人在服务端
        break;
      case ZJH:
        zhajinhuaRoomDic.load();
        break;
      case WKNH:
        wknhRoomDic.load();
        break;
      default:
        break;
    }
  }

  /**
   * schedule机器人玩家.
   * 
   * @param players .
   */
  private void schedulePlayers() {
    try {
      // 服务器端口开放才启动玩家
      if (!NetUtil.remotePortAbled(serverIp, serverPort)) {
        LOG.warn("远程IP[{}]端口[{}]不可用不能schedule机器人", serverIp, serverPort);
        return;
      }

      for (RobotConfigDomWrapper robotCfg : robotConfigDic.list()) {
        schedulePlayers(robotCfg);
      }
    } catch (Exception e) {
      LOG.error("schedulePlayers异常", e);
    }
  }

  /**
   * schedule游戏房间玩家,当机器人高于或低于配置时，及时剔除或者补充机器人.
   * 
   * @param robotCfg .
   */
  private void schedulePlayers(RobotConfigDomWrapper robotCfg) {
    // 没有游戏和房间的玩家可以被使用的玩家
    List<RobotDomain> usableRobotDoms = new ArrayList<>();
    // 该游戏房间的玩家
    List<Player> roomPlayers = new ArrayList<>();
    Game game = Game.getGame(robotCfg.getGame());
    int roomId = robotCfg.getRoom();
    // 当前时刻应该在线的机器人数
    int robotNum = robotCfg.getRobotNum(LocalTime.now().getHour());

    for (RobotDomain robotDom : robotDoms.values()) {
      long playerId = robotDom.getId();
      Player player = players.get(playerId);

      if (player == null) {
        usableRobotDoms.add(robotDom);
      } else if (player.game() == game && player.roomId == roomId && player.isChannelActive()
          && player.position != null) {
        roomPlayers.add(player);
      } else if (player.game() == game && player.roomId == roomId && player.isChannelActive()
          && player.position == null) {
        LOG.info("[{}][{}]中未登录机器人[{}]", game.getDesc(), roomId, player.playerId);
        // 取消移除schedule
        if (player.removeSchedule != null) {
          player.removeSchedule.cancel(false);
        }
        // 触发新的登录任务
        player.removeSchedule = scheduler.schedule(() -> {
          // 如果30后的状态还是尚未登录，说明用户应该是登录不上(重复登陆，关闭连接),移除玩家,等待下次登陆重试
          Player p = players.get(playerId);
          if (p != null && p.isChannelActive() && p.position == null) {
            removePlayer(p);
          }
        }, 30, TimeUnit.SECONDS);
      } else if (player.game() == game && player.roomId == roomId && !player.isChannelActive()) {
        players.remove(player.playerId);
        player = null;
      }
    }

    if (robotNum > roomPlayers.size()) { // 人数不足，补充人数
      for (int i = 0; i < usableRobotDoms.size() && i < robotNum - roomPlayers.size(); i++) {
        RobotDomain robotDom = usableRobotDoms.get(i);
        Player player = createPlayer(robotCfg, robotDom);
        if (player != null) {
          players.put(player.playerId, player);
          scheduler.schedule(() -> {
            player.login(serverIp, serverPort);
          }, RandCodeUtil.random(1, 30), TimeUnit.SECONDS);
        }
      }
    } else if (robotNum < roomPlayers.size()) { // 人数过多,机器人退出登录
      for (int i = 0; i < roomPlayers.size() && i < roomPlayers.size() - robotNum; i++) {
        roomPlayers.get(i).delayLogout();
      }
    }

    // schedule游戏房间玩家进入游戏
    for (Player p : roomPlayers) {
      scheduler.schedule(() -> p.enterGame(), RandCodeUtil.random(5, 30), TimeUnit.SECONDS);
    }
  }

  /**
   * 从RobotDomain创建玩家.
   * 
   * @param robotCfg .
   * @param robotDom .
   * @return .
   */
  public Player createPlayer(RobotConfigDomain robotCfg, RobotDomain robotDom) {
    long playerId = robotDom.getId();
    String userName = robotDom.getUserName();
    int roomId = robotCfg.getRoom();
    // 初始金币
    int initGold = RandCodeUtil.random(robotCfg.getGoldLower(), robotCfg.getGoldUpper());
    // 牌桌游戏局数
    int tableGameNum =
        RandCodeUtil.random(robotCfg.getTableGameLower(), robotCfg.getTableGameUpper());
    // 总游戏局数
    int totalGameNum =
        RandCodeUtil.random(robotCfg.getTotalGameLower(), robotCfg.getTotalGameUpper());
    Player player = null;
    GamesDomain gamesDomain = gamesDic.get(robotCfg.getGame());
    if (gamesDomain != null && gamesDomain.getActive()) {
      LOG.info("{} 游戏  启动着", gamesDomain.getRemark());
      switch (Game.getGame(robotCfg.getGame())) {
        case BAIREN_NIUNIU:
          BairenniuniuRoomDomain bairenniuniuRoomDomain = bairenniuniuRoomDic.get(roomId);
          if (bairenniuniuRoomDomain != null
              && bairenniuniuRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new BaiRenNiuNiuPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, bairenniuniuRoomDomain);
          }
          break;

        case ERREN_NIUNIU:
          ErrenniuniuRoomDomain errenniuniuRoomDomain = errenniuniuRoomDic.get(roomId);
          if (errenniuniuRoomDomain != null
              && errenniuniuRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new ErRenNiuNiuPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, errenniuniuRoomDomain);
          }
          break;
        case ERREN_TEXAPOKER:
          ErrentexaporkerRoomDomain errentexaporkerRoomDomain = errentexaporkerRoomDic.get(roomId);
          if (errentexaporkerRoomDomain != null
              && errentexaporkerRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new ErrenTexaspokerPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, errentexaporkerRoomDomain);
          }
          break;
        case FOURS_SHOP:
          FoursShopRoomDomain foursShopRoomDomain = foursShopRoomDic.get(roomId);
          if (foursShopRoomDomain != null
              && foursShopRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new FoursShopPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, foursShopRoomDomain);
          }
          break;
        case HAPPY_FIVE:
          HappyfiveRoomDomain happyfiveRoomDomain = happyfiveRoomDic.get(roomId);
          if (happyfiveRoomDomain != null
              && happyfiveRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new HappyFivePlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, happyfiveRoomDomain);
          }
          break;
        case HORCERACE:
          HorseRaceRoomDomain horseRaceRoomDomain = horseRaceRoomDic.get(roomId);
          if (horseRaceRoomDomain != null
              && horseRaceRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new HorseRacePlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, horseRaceRoomDomain);
          }
          break;
        case JCBY:
          JcbyRoomDomain jcbyRoomDomain = jcbyRoomDic.get(roomId);
          if (jcbyRoomDomain != null && jcbyRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new JcbyPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, jcbyRoomDomain);
          }
          break;
        case LKBY:
          LkpyRoomDomain lkpyRoomDomain = lkpyRoomDic.get(roomId);
          if (lkpyRoomDomain != null && lkpyRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new LkbyPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, lkpyRoomDomain);
          }
          break;
        case FQZS:
          SharkRoomDomain sharkRoomDomain = sharkRoomDic.get(roomId);
          if (sharkRoomDomain != null
              && sharkRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new SharkPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, sharkRoomDomain);
          }
          break;
        case SHUI_HU_ZHUAN:
          ShuihuRoomDomain shuihuRoomDomain = shuihuRoomDic.get(roomId);
          if (shuihuRoomDomain != null
              && shuihuRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new ShuiHuPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, shuihuRoomDomain);
          }
          break;
        case SIREN_NIUNIU:
          SirenniuniuRoomDomain sirenniuniuRoomDomain = sirenniuniuRoomDic.get(roomId);
          if (sirenniuniuRoomDomain != null
              && sirenniuniuRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new SiRenNiuNiuPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, sirenniuniuRoomDomain);
          }
          break;
        case TEXAPOKER:
          TexaporkerRoomDomain texaporkerRoomDomain = texaporkerRoomDic.get(roomId);
          if (texaporkerRoomDomain != null
              && texaporkerRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new TexaspokerPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, texaporkerRoomDomain);
          }
          break;
        case TONGBI_NIUNIU:
          TongbiniuniuRoomDomain tongbiniuniuRoomDomain = tongbiniuniuRoomDic.get(roomId);
          if (tongbiniuniuRoomDomain != null
              && tongbiniuniuRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new TongBiNiuNiuPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, tongbiniuniuRoomDomain);
          }
          break;
        case BACCARAT:
          BaccaratRoomDomain baccaratRoomDomain = baccaratRoomDic.get(roomId);
          if (baccaratRoomDomain != null
              && baccaratRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new BaccaratPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, baccaratRoomDomain);
          }
          break;
        case WEISHUWU:
          WeishuwuRoomDomain weishuwuRoomDomain = weishuwuRoomDic.get(roomId);
          if (weishuwuRoomDomain != null
              && weishuwuRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new WeishuwuPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, weishuwuRoomDomain);
          }
          break;
        case DOU_DI_ZHU: // 斗地主比赛机器人在服务端
          break;
        case ZJH:
          ZhajinhuaRoomDomain zhajinhuaRoomDomain = zhajinhuaRoomDic.get(roomId);
          if (zhajinhuaRoomDomain != null
              && zhajinhuaRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new ZjhPlayer(playerId, userName, roomId, initGold, totalGameNum, tableGameNum,
                robotCfg, zhajinhuaRoomDomain);
          }
          break;
        case WKNH:
          WknhRoomDomain wknhRoomDomain = wknhRoomDic.get(roomId);
          if (wknhRoomDomain != null && wknhRoomDomain.getIsActive() == RoomActiveConstant.ACTIVE) {
            player = new WknhPlayer(playerId, userName, roomId, initGold, totalGameNum,
                tableGameNum, robotCfg, wknhRoomDomain);
          }
          break;
        default:
          break;
      }
    }

    return player;
  }

  /**
   * 是否是机器人.
   * 
   * @param playerId .
   * @return .
   */
  public boolean isRobot(long playerId) {

    return robotDoms.containsKey(playerId);
  }

  /**
   * 移除玩家.
   * 
   * @param player .
   */
  public void removePlayer(Player player) {
    long playerId = player.playerId;
    if (players.remove(playerId) != null) {
      LOG.info("[{}]机器人玩家[{}][{}]退出游戏 ", player.game().getDesc(), player.userName, playerId);
      player.close();
      player.clear();
      player = null;
    }
  }

  /**
   * 获取玩家.
   * 
   * @param playerId .
   */
  public Player getPlayer(long playerId) {

    return players.get(playerId);
  }
}
